package cn.trkj.server.util;

import lombok.NoArgsConstructor;
import lombok.SneakyThrows;
import org.apache.commons.lang3.time.DateFormatUtils;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.management.ManagementFactory;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * 时间工具类
 *
 * @author admin
 */
@NoArgsConstructor
public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
    public static String YYYY = "yyyy";

    public static String YYYY_MM = "yyyy-MM";

    public static String YYYY_MM_DD = "yyyy-MM-dd";
    public static String YYYYMMDD = "yyyyMMdd";

    public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

    public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

    public static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private static String[] parsePatterns = {
            "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
            "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
            "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
    private static SimpleDateFormat dffdL = new SimpleDateFormat(YYYY_MM_DD);

    /**
     * 获取当前Date型日期
     *
     * @return Date() 当前日期
     */
    public static Date getNowDate() {
        return new Date();
    }

    /**
     * 获取时间戳
     */
    public static String getTimestamp() {
        return String.valueOf(System.currentTimeMillis());
    }

    /**
     * 获取当前日期, 默认格式为yyyy-MM-dd
     *
     * @return String
     */
    public static String getDate() {
        return dateTimeNow(YYYY_MM_DD);
    }

    public static String getYear() {
        return dateTimeNow(YYYY_MM_DD).substring(0, 4);
    }

    public static String getDateName() {
        return dateTimeNow("yyyy年MM月dd日");
    }

    public static final String getTime() {
        return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
    }

    public static final String dateTimegetdate() {
        return dateTimeNow(YYYYMMDDHHMMSS);
    }

    public static final String dateTimeNow(final String format) {
        return parseDateToStr(format, new Date());
    }

    public static final String dateTime(final Date date) {
        return parseDateToStr(YYYY_MM_DD, date);
    }

    public static final String parseDateToStr(final String format, final Date date) {
        return new SimpleDateFormat(format).format(date);
    }

    public static final Date dateTime(final String format, final String ts) {
        try {
            return new SimpleDateFormat(format).parse(ts);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 系统当前时间到0点的秒数
     */
    public static Long getSecondsTobeforedawn() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DAY_OF_YEAR, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return (cal.getTimeInMillis() - System.currentTimeMillis()) / 1000;
    }

    /**
     * 将标准日期格式转为 ：yyyy-MM-dd HH:mm:ss
     */
    public static final String dateFormat(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(date);
    }

    public static final String dateFormat1(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String format = sdf.format(date);
        return format;
    }

    public static final String dateFormatDate(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(date);
    }


    /**
     * 日期路径 即年/月/日 如2018/08/08
     */
    public static final String datePath() {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyy/MM/dd");
    }

    public static Date strToDate(String strDate) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        ParsePosition pos = new ParsePosition(0);
        Date strtodate = formatter.parse(strDate, pos);
        return strtodate;
    }

    /**
     * 获得指定日期的后一天
     * true  前一天
     * false 一天
     *
     * @param
     * @return
     */
    @SneakyThrows(ParseException.class)
    public static Date getSpecifiedDayAfter(Date date2, boolean is) {
        Calendar c = Calendar.getInstance();
        String format = DateFormatUtils.format(date2, YYYY_MM_DD);
        Date date = new SimpleDateFormat(YYYY_MM_DD).parse(format);

        c.setTime(date);
        int day = c.get(Calendar.DATE);
        if (is) {
            c.set(Calendar.DATE, day + 1);
        } else {
            c.set(Calendar.DATE, day - 1);
        }
        String dayAfter = new SimpleDateFormat(YYYY_MM_DD).format(c.getTime());
        Date date1 = parseDate(dayAfter);
        return date1;
    }


    /**
     * 日期路径 即年/月/日 如20180808
     */
    public static final String dateTime() {
        Date now = new Date();
        return DateFormatUtils.format(now, YYYY_MM_DD);
    }

    public static final String getDateUtil() {
        Date now = new Date();
        return DateFormatUtils.format(now, YYYYMMDD);
    }

    /**
     * 日期型字符串转化为日期 格式
     */
    public static Date parseDate(Object str) {
        if (str == null) {
            return null;
        }
        try {
            return parseDate(str.toString(), parsePatterns);
        } catch (ParseException e) {
            return null;
        }
    }

    public static Date fromDateStringFixedL(String dateString) throws ParseException {
        Date date = null;
        synchronized (dffdL) {
            date = dffdL.parse(dateString);
        }
        return date;
    }


    public static Date parseDateTime(String str) {
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            //使用SimpleDateFormat的parse()方法生成Date
            return sf.parse(str);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 获取服务器启动时间
     */
    public static Date getServerStartDate() {
        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
        return new Date(time);
    }

    /**
     * 计算两个时间差
     */
    public static String getDatePoor(Date endDate, Date nowDate) {
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        // long ns = 1000;
        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - nowDate.getTime();
        // 计算差多少天
        long day = diff / nd;
        // 计算差多少小时
        long hour = diff % nd / nh;
        // 计算差多少分钟
        long min = diff % nd % nh / nm;
        // 计算差多少秒//输出结果
        // long sec = diff % nd % nh % nm / ns;
        return day + "天" + hour + "小时" + min + "分钟";
    }


    /**
     * 判断俩个时间是否同一天
     *
     * @param date1
     * @param date2
     * @return
     */
    public static boolean isSameDay(Date date1, Date date2) {
        if (date1 == null || date2 == null) {
            throw new IllegalArgumentException("时间为空");
        }
        final Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);
        final Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
        return isSameDay(cal1, cal2);
    }

    /**
     * 计算两个时间差几天
     *
     * @param endDate
     * @param nowDate
     * @return
     */
    public static long getDatePoorDay(Date endDate, Date nowDate) {
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        // long ns = 1000;
        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - nowDate.getTime();
        // 计算差多少天
        long day = diff / nd;
        return day;
    }


    public static long getDateTime(Date endDate, Date nowDate) {
//        long nd = 1000 * 24 * 60 * 60;
//        long nh = 1000 * 60 * 60;
//        long nm = 1000 * 60;
        // long ns = 1000;
        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - nowDate.getTime();
//        // 计算差多少天
//        long day = diff / nd;
//        // 计算差多少小时
//        long hour = diff % nd / nh;
//        // 计算差多少分钟
//        long min = diff % nd % nh / nm;
        return diff / (24 * 60 * 60 * 1000);
    }


    //根据起止时间计算天数
    @SneakyThrows(ParseException.class)
    public static long getDateCe(String stateTime, String endTime) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date state = sdf.parse(stateTime);
        Date end = sdf.parse(endTime);

        long stateTimeLong = state.getTime();
        long endTimeLong = end.getTime();
        // 结束时间-开始时间 = 天数
        return (endTimeLong - stateTimeLong) / (24 * 60 * 60 * 1000);
    }

    //根据起始值以及相差天数计算计算结尾值, 起始值算一给天 格式 [)
    public static String getDateCeLast(String stateTime, long days) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sdfResult = new SimpleDateFormat("yyyyMMdd");
        try {
            Date state = sdfResult.parse(stateTime);
            long stateTimeLong = state.getTime();
            long endTimeLong = days * (24 * 60 * 60 * 1000) + stateTimeLong;
            Date date = new Date(endTimeLong);
            String format = sdfResult.format(date);
            return format;
        } catch (ParseException e) {
        }
        return String.valueOf(-1L);
    }

    public static Date dateAdd(Date date, long i) {
        long ldate = date.getTime();
        ldate += i * 24 * 60 * 60 * 1000;
        return new Date(ldate);
    }

    public static Date addDays(Date date, int i) {
        return dateAdd(date, i);
    }

    public static String addDay(Date date, int i) {
        return DateFormatUtils.format(dateAdd(date, i), "yyyy-MM-dd");
    }


    public static String addDay1(Date date, int i) {
        return DateFormatUtils.format(dateAdd(date, i), "yyyyMMdd");
    }
    /**
     * 日期   顺应增加一年  或者 减少一年 （负数）
     *
     * @param date
     * @param value
     * @return
     */
    public static String dateyear(Date date, int value) {
        GregorianCalendar calender = new GregorianCalendar();
        calender.setTime(date);
        calender.add(Calendar.YEAR, value);
        return DateFormatUtils.format(calender.getTimeInMillis(), "yyyy-MM-dd");
    }

    /**
     * 日期   顺应增加一月 （正数） 或者 减少一月 （负数）
     *
     * @param date
     * @param i
     * @return
     */
    public static String dateMonth(Date date, int i) {
        String stringDate = "";
        Calendar calendar = new GregorianCalendar();
        calendar.add(Calendar.MONTH, i);
        date = calendar.getTime();
        stringDate = sdf.format(date);
        return stringDate;
    }

    /**
     * 顺增几个月
     */
    public static String dateMonths(Date date, int i) {
        String stringDate = "";
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, i);
        date = calendar.getTime();
        stringDate = dffdL.format(date);
        return stringDate;
    }

    /**
     * 日期   顺应增加一周 （正数） 或者 减少一周 （负数）
     *
     * @param date
     * @param i
     * @return
     */
    public static String dateWeek(Date date, int i) {
        String stringDate = "";
        Calendar calendar = new GregorianCalendar();
        calendar.add(Calendar.WEEK_OF_MONTH, i);
        date = calendar.getTime();
        stringDate = sdf.format(date);
        return stringDate;
    }

    public static String dateString(Date date) {
        SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd");
        return ft.format(date);
    }

    /**
     * 时间比大小 t1>t2 返回1，t1=t2 返回0
     *
     * @param t1
     * @param t2
     * @return
     */
    @SneakyThrows(ParseException.class)
    public static int timeCompare(String t1, String t2) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        c1.setTime(formatter.parse(t1));
        c2.setTime(formatter.parse(t2));
        int result = c1.compareTo(c2);
        return result;
    }

    /**
     * 时间比较大小
     *
     * @param date1
     * @param date2
     * @return
     */
    public static int compareDate(Date date1, Date date2) {
        if (date1.getTime() > date2.getTime()) {
            return -1;
        } else if (date1.getTime() < date2.getTime()) {
            return 1;
        } else {
            return 0;
        }
    }

    @SneakyThrows(ParseException.class)
    public static int compareDate1(Date date1, Date date2) {
        //日期传进先格式化
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //然后判断字符串
        String d1 = dateFormat.format(date1);
        String d2 = dateFormat.format(date2);
        if (d1.substring(11, 19).equals("00:00:00")) {
            d1 = d1.replace("00:00:00", "23:59:59");
        }
        if (d2.substring(11, 19).equals("00:00:00")) {
            d2 = d2.replace("00:00:00", "23:59:59");
        }
        date1 = dateFormat.parse(d1);
        date2 = dateFormat.parse(d2);
        int i = date1.compareTo(date2);
        return i;
    }

    /***
     * java 转换日期 lht
     */
    public static Date addDate(String date, long day) {
        Date date1 = parseDateTime(date);
        // 得到指定日期的毫秒数
        long time = date1.getTime();
        // 要加上的天数转换成毫秒数
        day = day * 24 * 60 * 60 * 1000;
        // 相加得到新的毫秒数
        time += day;
        // 将毫秒数转换成日期
        return new Date(time);
    }

    /**
     * 给一个日期获得其他的日期
     *
     * @param farmat 返回日期格式
     * @param date   传入的初始日期
     * @param num    想要得到的哪天（正数：代表后num天，负数：代表前num天）
     * @return 格式字符串的日期
     */
    public static String getAnotherYear(String farmat, String date, Integer num) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(farmat);
        Date date_ = sdf.parse(date);// 将字符串转化为时间格式
        Calendar calendar = Calendar.getInstance(); // 得到日历
        calendar.setTime(date_);// 把开始日期赋给日历
//        calendar.add(Calendar.DAY_OF_MONTH, num); // 设置为num天
//        calendar.add(Calendar.HOUR_OF_DAY, num); // 设置为num小时
//        calendar.add(Calendar.MONTH, num); // 设置为num月
        calendar.add(Calendar.YEAR, num); // 设置为num年
        Date resultDate = calendar.getTime(); // 得到时间
        return sdf.format(resultDate);
    }

    public static String getAnotherMonth(String farmat, String date, Integer num) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(farmat);
        Date date_ = sdf.parse(date);// 将字符串转化为时间格式
        Calendar calendar = Calendar.getInstance(); // 得到日历
        calendar.setTime(date_);// 把开始日期赋给日历
//        calendar.add(Calendar.DAY_OF_MONTH, num); // 设置为num天
//        calendar.add(Calendar.HOUR_OF_DAY, num); // 设置为num小时
        calendar.add(Calendar.MONTH, num); // 设置为num月
//        calendar.add(Calendar.YEAR, num); // 设置为num年
        Date resultDate = calendar.getTime(); // 得到时间
        return sdf.format(resultDate);
    }

    public static String getAnotherDay(String farmat, String date, Integer num) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(farmat);
        Date date_ = sdf.parse(date);// 将字符串转化为时间格式
        Calendar calendar = Calendar.getInstance(); // 得到日历
        calendar.setTime(date_);// 把开始日期赋给日历
        calendar.add(Calendar.DAY_OF_MONTH, num); // 设置为num天
//        calendar.add(Calendar.HOUR_OF_DAY, num); // 设置为num小时
//        calendar.add(Calendar.MONTH, num); // 设置为num月
//        calendar.add(Calendar.YEAR, num); // 设置为num年
        Date resultDate = calendar.getTime(); // 得到时间
        return sdf.format(resultDate);
    }

    /**
     * 获取服务器启动时间
     */
    public static String getBatchNo() {
        //生成批次流水号:年(后2位)+月(2位)+日(2位)+小时(2位)+分钟(2位)+秒(2位)+毫秒(3位)+04001
        String batchNo = null;
        String s = DateUtils.dateTimegetdate().substring(2);
        Calendar cal = Calendar.getInstance();
        String s1 = String.valueOf(cal.get(Calendar.MILLISECOND));
        batchNo = s + s1 + "04001";
        return batchNo;
    }


    /**
     *  * 计算两个日期之间的周末天数
     *  * @author yan
     *  *
     *  
     */
    public static int computeHolidays(Date t1, Date t2) throws ParseException {
        //初始化第一个日期
        Calendar cal1 = Calendar.getInstance();
        //初始化第二个日期，这里的天数可以随便的设置
        Calendar cal2 = Calendar.getInstance();

        // 设置传入的时间格式
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 指定一个日期
        Date date1 = dateFormat.parse(dateFormat.format(t1));
        Date date2 = dateFormat.parse(dateFormat.format(t2));
        // 对 calendar 设置为 date 所定的日期
        cal1.setTime(date1);
        cal2.setTime(date2);

        int holidays = 0;
        //确定一个 大日期
        if (cal1.compareTo(cal2) > 0) {
            Calendar temp = cal1;
            cal1 = cal2;
            cal2 = temp;
            temp = null;
        }
        while (cal1.compareTo(cal2) <= 0) {
            if (cal1.get(Calendar.DAY_OF_WEEK) == 1 || cal1.get(Calendar.DAY_OF_WEEK) == 7) {
                holidays++;
            }
            cal1.add(Calendar.DAY_OF_YEAR, 1);

        }
        return holidays;
    }


    private static String jiejiari(String httpUrl) {
        BufferedReader reader = null;
        String result = null;
        StringBuffer sbf = new StringBuffer();
        try {
            URL url = new URL(httpUrl);
            HttpURLConnection connection = (HttpURLConnection) url
                    .openConnection();
            connection.setRequestMethod("GET");
            InputStream is = connection.getInputStream();
            reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
            String strRead = null;
            while ((strRead = reader.readLine()) != null) {
                sbf.append(strRead);
                sbf.append("\r\n");
            }
            reader.close();
            result = sbf.toString();
        } catch (Exception e) {
        }
        return result;
    }

}
